package com.jch.dm3_two_phase_termination.reusable_code;

import java.lang.ref.WeakReference;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicInteger;

public class TerminationToken {

    protected volatile boolean toShutdown = false;
    public final AtomicInteger reservations = new AtomicInteger(0);

    /**
     * 多个可停止线程实例共享一个TerminationToken实例的情况下，该队列用于记录那些共享TerminationToken实例的可停止线程，
     * 以便尽可能减少锁的使用的情况下，实现这些线程的停止。
     */
    private final Queue<WeakReference<Terminatable>> coordinatedThreads;

    public TerminationToken(){
        coordinatedThreads = new ConcurrentLinkedDeque<>();
    }

    public boolean isToShutdown() {
        return toShutdown;
    }

    protected void setToShutdown(boolean toShutdown){
        this.toShutdown = true;
    }

    protected void register(Terminatable thread){
        coordinatedThreads.add(new WeakReference<Terminatable>(thread));
    }

    /**
     * 通知实例：共享该实例的一个线程停止了，以便其停止其它未被停止的未被停止的线程。
     * @param thread 已停止的线程
     */
    protected void notifyThreadTermination(Terminatable thread){
        WeakReference<Terminatable> wrThread;
        Terminatable otherThread;
        while(null != (wrThread = coordinatedThreads.poll())){
            otherThread = wrThread.get();
            if (null != otherThread && otherThread != thread){
                otherThread.terminate();
            }
        }
    }


}
